// Workers connect to the Broker-ZMQ_DEALER, recive and process the requests from Clients.
#include "zguide/C/zhelpers.h"
#include "libzmq/zmq.h"
#include <iostream>
#include <thread>
#include "../protobuf/msg.pb.h"
#include <dlfcn.h>

typedef char *(*MYPROC)(const char *);

void recvMsg(void **context)
{
	//  Socket to talk to clients
	void *responder = zmq_socket(*context, ZMQ_REP);
	zmq_connect(responder, "tcp://localhost:5560");

	while (true)
	{
		//  Wait for next request from client
		char *strMsg = s_recv(responder);

		msg m;
		m.ParseFromString(strMsg);

		std::cout << "req:" << m.funcid() << std::endl;

		std::string strRtn;
		MYPROC ProcAdd;
		void *handle = dlopen("/mnt/d/ubuntu/zmq/builds/libmodules.so", RTLD_GLOBAL | RTLD_NOW);
		if (handle != NULL)
		{
			ProcAdd = (MYPROC)dlsym(handle, m.funcid().c_str());
			if (NULL != ProcAdd)
			{
				strRtn = (ProcAdd)(m.data().c_str());
			}
			else
			{
				std::cout << "undefined " << m.funcid() << std::endl;
			}
			dlclose(handle);
		}
		else
		{
			std::cout << "dlopen failed" << std::endl;
		}

		free(strMsg);

		//  Do some 'work'
		//sleep(1000);

		//  Send reply back to client
		s_send(responder, const_cast<char*>(strRtn.c_str()));
	}

	zmq_close(responder);
}

int main(void)
{
	void *context = zmq_ctx_new();

	std::thread t1(recvMsg, &context);
	std::thread t2(recvMsg, &context);
	t1.join();
	t2.join();

	zmq_ctx_destroy(context);
	return 0;
}
